package utils

import (
	"encoding/binary"
	"errors"
	"fmt"
	"log"
	"os"
	"regexp"
	"strconv"
	"strings"

	"github.com/RuiGuangServer/config"
	"github.com/RuiGuangServer/logs"
	"github.com/klauspost/compress/zstd"
)

var uuidRegex = regexp.MustCompile(`^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$`)

// PathExists 判断文件夹是否存在
func PathExists(path string) bool {
	_, err := os.Stat(path)
	if err == nil {
		return true
	}
	if os.IsNotExist(err) {
		return false
	}
	return false
}

// CreatFolder 创建文件夹
func CreatFolder(path string) {
	unixPath := strings.ReplaceAll(path, "\\", "/")
	paths := strings.Split(unixPath, "/")
	var str string
	for i := range paths {
		str = paths[i] + "/"
		if len(str) != 0 && !PathExists(str) {
			_ = os.Mkdir(str, 0777)
		}
	}
}

func LogsStart() *logs.AsyncLogger {
	realSize := config.Config.LogSaveSize * 1024 * 1024
	path := "./logs"
	CreatFolder(path)
	logfile := path + "/log.log"
	logger, err := logs.NewFileLogger(logs.DEBUG, logfile, int64(realSize), "size")
	if err != nil {
		log.Fatalf("Failed to create logger: %v", err)
		return nil
	}
	return logger
}

func DataStart() *logs.AsyncLogger {
	realSize := config.Config.LogSaveSize * 1024 * 1024
	path := "./datas"
	CreatFolder(path)
	datafile := path + "/server.log"
	dataer, err := logs.NewFileLogger(logs.DEBUG, datafile, int64(realSize), "size")
	if err != nil {
		log.Fatalf("Failed to create dataer: %v", err)
		return nil
	}
	return dataer
}

func FastAnyToString(value any) string {
	switch v := value.(type) {
	case string:
		return v
	case []byte:
		return string(v)
	case int:
		return strconv.Itoa(v)
	case float64:
		return strconv.FormatFloat(v, 'f', -1, 64)
	case bool:
		if v {
			return "true"
		}
		return "false"
	case nil:
		return ""
	default:
		return fmt.Sprint(v)
	}
}

func IsValidUUID(uuid string) bool {
	return uuidRegex.MatchString(uuid)
}

//func SafeDeref[T any](ptr *T, defaultValue T) T {
//	if ptr != nil {
//		return *ptr
//	}
//	return defaultValue
//}

func ZstdToJson(data []byte) ([]byte, error) {
	if len(data) == 0 {
		return nil, errors.New("empty Awos data")
	}

	// 1. 解析头部
	hbuf := binary.LittleEndian.Uint16(data[:2])  // 可能表示扩展头长度
	fbuf := binary.LittleEndian.Uint16(data[2:4]) // 可能表示尾部长度

	// 2. 计算数据体范围
	star := 4 + int(hbuf)        // 头部长度+扩展头长度
	end := len(data) - int(fbuf) // 头部长度+扩展头长度+body长度
	fmt.Printf("star:%v,end:%v\n", star, end)
	if star > end || end > len(data) {
		return nil, errors.New("invalid header: star or end out of bounds")
	}
	body := data[star:end] // 压缩的数据体

	// 3. 将body转换为\x格式的十六进制字符串
	//var hexBuilder strings.Builder
	//for _, b := range body {
	//	hexBuilder.WriteString(fmt.Sprintf("\\x%02x", b))
	//}

	// 4. 输出结果（每行16个字节）
	//hexStr := hexBuilder.String()
	//// fmt.Println("Body in \\x format:")
	//for i := 0; i < len(hexStr); i += 16 * 4 { // 每个\xXX占4字符
	//	endIdx := min(i+16*4, len(hexStr))
	//	fmt.Println(hexStr[i:endIdx])
	//}

	decoder, err := zstd.NewReader(nil)
	if err != nil {
		return nil, fmt.Errorf("failed to create zstd decoder:%v", err)
	}
	defer decoder.Close()

	decompressed, err := decoder.DecodeAll(body, nil)
	if err != nil {
		return nil, fmt.Errorf("decompression failed:%v", err)
	}
	return decompressed, nil
}
